/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "realtime_audio_transcoder.h"
#include "aac_pcm_decoder.h"
#include "pcm_aac_encoder.h"
#include "utils_log.h"

#include <algorithm>

namespace {

constexpr int kDefaultPlaybackInputSampleRate = 24000; // 阿里云实时语音默认24k PCM
constexpr int kPlaybackOutputSampleRate = 16000;       // 本地播放器按16kHz配置
constexpr int kPlaybackBitrate = 128000;               // 16k AAC目标码率(比特/秒)

} // namespace

namespace El {
namespace Cloud {

RealtimeAudioTranscoder::RealtimeAudioTranscoder()
    : aacDecoder_(std::make_unique<El::Muxer::AacPcmDecoder>())
{
}

RealtimeAudioTranscoder::~RealtimeAudioTranscoder() = default;

bool RealtimeAudioTranscoder::Initialize()
{
    if (initialized_) {
        EL_WARN("RealtimeAudioTranscoder already initialized");
        return true;
    }

    // 初始化 AAC -> PCM 解码器
    // Qwen3-Omni 要求输入: 16kHz, 16bit, 单声道
    if (!aacDecoder_->Initialize(16000, 1, El::Muxer::AacPcmDecoder::PcmFormat::S16LE)) {
        EL_ERROR("Failed to initialize AAC decoder");
        return false;
    }
    EL_INFO("AAC decoder initialized: 16kHz, 1 channel, S16LE");

    // 初始化 PCM -> AAC 编码器 (默认按阿里云返回PCM 24kHz转16kHz AAC)
    if (!ReconfigurePlaybackEncoder(kDefaultPlaybackInputSampleRate, kPlaybackOutputSampleRate)) {
        EL_ERROR("Failed to initialize PCM encoder for playback path");
        return false;
    }

    initialized_ = true;
    EL_INFO("RealtimeAudioTranscoder initialized successfully");
    return true;
}

bool RealtimeAudioTranscoder::DecodeAacToPcm(const std::vector<uint8_t> &aacData, std::vector<uint8_t> &pcmData)
{
    if (!initialized_) {
        EL_ERROR("RealtimeAudioTranscoder not initialized");
        return false;
    }

    if (aacData.empty()) {
        pcmData.clear();
        return true;
    }

    // 推送AAC数据到解码器
    if (!aacDecoder_->ProcessInput(aacData.data(), aacData.size())) {
        EL_ERROR("Failed to process AAC input data");
        return false;
    }

    // 获取解码后的PCM数据
    if (!aacDecoder_->GetData(pcmData, false)) {
        EL_ERROR("Failed to get decoded PCM data");
        return false;
    }

    if (!pcmData.empty()) {
        EL_DEBUG("Decoded AAC to PCM: {} bytes -> {} bytes", aacData.size(), pcmData.size());
    }

    return true;
}

bool RealtimeAudioTranscoder::EncodePcmToAac(const std::vector<uint8_t> &pcmData, std::vector<uint8_t> &aacData)
{
    if (!initialized_) {
        EL_ERROR("RealtimeAudioTranscoder not initialized");
        return false;
    }

    if (pcmData.empty()) {
        aacData.clear();
        return true;
    }

    // 推送PCM数据到编码器
    if (!activeEncoder_) {
        EL_ERROR("Active PCM encoder not configured");
        return false;
    }

    if (!activeEncoder_->ProcessInput(pcmData.data(), pcmData.size())) {
        EL_ERROR("Failed to process PCM input data");
        return false;
    }

    // 获取编码后的AAC数据
    if (!activeEncoder_->GetData(aacData, false)) {
        EL_ERROR("Failed to get encoded AAC data");
        return false;
    }

    if (!aacData.empty()) {
        EL_DEBUG("Encoded PCM to AAC: {} bytes -> {} bytes", pcmData.size(), aacData.size());
    }

    return true;
}

bool RealtimeAudioTranscoder::FlushDecoder(std::vector<uint8_t> &pcmData)
{
    if (!initialized_) {
        EL_ERROR("RealtimeAudioTranscoder not initialized");
        return false;
    }

    if (!aacDecoder_->GetData(pcmData, true)) {
        EL_ERROR("Failed to flush AAC decoder");
        return false;
    }

    if (!pcmData.empty()) {
        EL_INFO("Flushed decoder: {} bytes of PCM data", pcmData.size());
    }

    return true;
}

bool RealtimeAudioTranscoder::FlushEncoder(std::vector<uint8_t> &aacData)
{
    if (!initialized_) {
        EL_ERROR("RealtimeAudioTranscoder not initialized");
        return false;
    }

    if (!activeEncoder_) {
        EL_ERROR("Active PCM encoder not configured");
        return false;
    }

    if (!activeEncoder_->GetData(aacData, true)) {
        EL_ERROR("Failed to flush PCM encoder");
        return false;
    }

    if (!aacData.empty()) {
        EL_INFO("Flushed encoder: {} bytes of AAC data", aacData.size());
    }

    return true;
}

bool RealtimeAudioTranscoder::ReconfigurePlaybackEncoder(int inputSampleRate, int outputSampleRate)
{
    playbackInputSampleRate_ = inputSampleRate > 0 ? inputSampleRate : kDefaultPlaybackInputSampleRate;
    playbackOutputSampleRate_ = outputSampleRate > 0 ? outputSampleRate : kPlaybackOutputSampleRate;
    playbackBitrate_ = std::max(16000, playbackOutputSampleRate_ * 8); // 简单按8倍采样率估算码率

    if (!ConfigureEncoders(playbackInputSampleRate_, playbackOutputSampleRate_)) {
        EL_ERROR("Failed to configure dual PCM encoders");
        return false;
    }

    EL_INFO("Dual PCM encoders configured: input {}Hz -> output {}Hz, bitrate {}bps", playbackInputSampleRate_,
            playbackOutputSampleRate_, playbackBitrate_);
    return true;
}

bool RealtimeAudioTranscoder::ConfigureEncoders(int inputSampleRate, int outputSampleRate)
{
    encoderA_ = std::make_unique<El::Muxer::PcmAacEncoder>();
    encoderB_ = std::make_unique<El::Muxer::PcmAacEncoder>();

    auto initEnc = [&](std::unique_ptr<El::Muxer::PcmAacEncoder> &enc) -> bool {
        return enc->Initialize(outputSampleRate, 1, El::Muxer::PcmAacEncoder::PcmFormat::S16LE, playbackBitrate_,
                               inputSampleRate, 1);
    };

    if (!initEnc(encoderA_) || !initEnc(encoderB_)) {
        EL_ERROR("Failed to initialize both encoder instances");
        encoderA_.reset();
        encoderB_.reset();
        activeEncoder_ = nullptr;
        standbyEncoder_ = nullptr;
        return false;
    }

    activeEncoder_ = encoderA_.get();
    standbyEncoder_ = encoderB_.get();
    return true;
}

bool RealtimeAudioTranscoder::FlushActiveAndRotate(std::vector<uint8_t> &tailAac)
{
    if (!initialized_) {
        EL_ERROR("RealtimeAudioTranscoder not initialized");
        return false;
    }
    if (!activeEncoder_ || !standbyEncoder_) {
        EL_ERROR("Encoders not configured for A/B rotation");
        return false;
    }

    // 刷新当前活动编码器，取出尾部 AAC
    if (!activeEncoder_->GetData(tailAac, true)) {
        EL_ERROR("Failed to flush active encoder");
        return false;
    }

    // 立刻切换到备用编码器，供下一段直接使用
    std::swap(activeEncoder_, standbyEncoder_);
    EL_INFO("Switched encoders: standby -> active");

    // 将刚刚 flushed 的编码器快速复位，作为新的备用
    if (!standbyEncoder_->Reset()) {
        EL_WARN("Failed to reset previous active (now standby) encoder");
    }

    return true;
}

} // namespace Cloud
} // namespace El
